A using-directive (e.g., using namespace std;
) makes names from another namespace available in the current scope. It should only be
used when those names do not create an ambiguity with other names. Otherwise, it is better to fully qualify the names you want to use.
The effect of using-directives inside a function body ceases at the end of the current scope. However, when the using-directives are at the global
or namespace scope, their effects propagate to the rest of the scope.
When you write a header file, you don’t know from which contexts it will be included. Therefore, if this header contains using-directives at the
global or namespace scope, you cannot be sure that they will not create ambiguities in some of the including contexts. Those ambiguities could lead to
compilation failures or, worse, to a different function being selected by overload resolution depending on the order of inclusion of headers.
This rule will raise an issue on using-directives in header files.
Noncompliant code example
// f1.h
void foo ( char_t a );
namespace NS1
{
void foo( int32_t a );
}
inline void bar ( )
{
foo ( 0 );
}
// f2.h
namespace NS1
{
}
using namespace NS1; // Noncompliant
// f1.cc
#include "f1.h"
#include "f2.h"
int32_t m1 ( )
{
bar ( ); // bar calls foo ( char_t );
}
// f2.cc
#include "f2.h"
#include "f1.h"
void m2 ( )
{
bar ( ); // bar calls foo ( int32_t );
}
Exceptions
Using-declarations (e.g., using std::cout;
) behave in the same way but only for one name. This rule does not apply to them because
their scope is much narrower.
Additionally, since it isn’t easy to fully qualify the content of the std::literals
and std::placeholders
namespaces,
this rule doesn’t raise violations for using-directives that target these namespaces or their sub-namespaces, such as
std::literals::chrono_literals
.